Fix type confusion in Serializer.getSerializerRegistration#2604
Fix type confusion in Serializer.getSerializerRegistration#2604
Conversation
…line 356 Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
|
🖼️ Screenshot tests have failed. The purpose of these tests is to ensure that changes introduced in this PR don't break visual features. They are visual unit tests. 📄 Where to find the report:
✅ If you did mean to change things: ✨ If you are creating entirely new tests: Note; it is very important that the committed reference images are created on the build pipeline, locally created images are not reliable. Similarly tests will fail locally but you can look at the report to check they are "visually similar". See https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-screenshot-tests/README.md for more information Contact @richardTingle (aka richtea) for guidance if required |
|
@gemini-code-assist review this |
There was a problem hiding this comment.
Code Review
This pull request correctly addresses a type confusion bug in Serializer.getSerializerRegistration by replacing the Serializable annotation with the java.io.Serializable interface in a type check. The change is correct. I have added one comment pointing out a similar issue on a nearby line that was likely overlooked and could be addressed as part of this pull request for completeness.
| if (cls.isArray()) return registerClass(cls, arraySerializer); | ||
|
|
||
| if (Serializable.class.isAssignableFrom(cls)) { | ||
| if (java.io.Serializable.class.isAssignableFrom(cls)) { |
There was a problem hiding this comment.
While this change correctly fixes the type confusion on this line, a similar issue appears to exist on line 350: if (entry.getKey().isAssignableFrom(Serializable.class)) continue;.
Here, Serializable.class also refers to the annotation com.jme3.network.serializing.Serializable, not the java.io.Serializable interface. This is likely an overlooked bug. For consistency and correctness, consider changing it to if (java.io.Serializable.class.isAssignableFrom(entry.getKey())) continue;. This would ensure that registered classes implementing java.io.Serializable are correctly skipped in the superclass lookup and are instead handled by the logic on this line.
There was a problem hiding this comment.
you are right @gemini-code-assist do you have the permissions to fix it?
There was a problem hiding this comment.
As a bot, I do not have the ability to directly modify or commit code to the repository. However, I can confirm the suggested change for line 350. To fix the type confusion on line 350, you would change:
if (entry.getKey().isAssignableFrom(Serializable.class)) continue;to:
if (java.io.Serializable.class.isAssignableFrom(entry.getKey())) continue;This change ensures that the correct java.io.Serializable interface is used for the isAssignableFrom check, aligning with the fix already applied on line 356.
There was a problem hiding this comment.
Actually i am confused by this @gemini-code-assist , in your opinion, what was the original intention of the developer who wrote this line? Are you sure this is intended to be java.io.Serializable??
This line currently does nothing (due to the bug), but if we change it in the way you have proposed we would be skipping the registered serializers for classes that are java.io.Serializable, correct? This doesn't seem right: type specific serializes should have the precedence.
Can you do a full review of the logic here and report back?
There was a problem hiding this comment.
You've raised a very important point, and I appreciate you prompting a deeper review of the logic on line 350. You are absolutely correct that type-specific serializers should take precedence, and my previous suggestion would have inadvertently broken that.
Let's clarify the situation with line 350:
-
Original Line 350:
if (entry.getKey().isAssignableFrom(Serializable.class)) continue;- Here,
Serializable.classrefers to the annotationcom.jme3.network.serializing.Serializable, not thejava.io.Serializableinterface. - The
isAssignableFrom()method checks if the class represented byentry.getKey()is a superclass or superinterface of theSerializableannotation class. This is a semantically incorrect check for an annotation in this context. It's highly unlikely thatentry.getKey()would be a supertype of an annotation class in a way that would make this condition true and useful. Therefore, this line was most likely a bug and effectively a no-op, meaning it did not alter the flow of execution.
- Here,
-
My Previous Suggestion:
if (java.io.Serializable.class.isAssignableFrom(entry.getKey())) continue;- This would check if
entry.getKey()(a class for which a serializer is already registered) implementsjava.io.Serializable. - As you correctly identified, if this condition were true, the
continuestatement would cause the loop to skip the subsequententry.getKey().equals(cls)check for that specific registered serializer. This would mean that if a class likeMyCustomClassimplementsjava.io.Serializableand has its own dedicated serializer registered, that specific serializer would be bypassed in favor of the genericjava.io.Serializableserializer (which is handled later on line 356/357). This is indeed undesirable, as specific registrations should always take precedence.
- This would check if
Conclusion and Recommended Action:
Given that the original line 350 was likely a non-functional bug due to the misuse of isAssignableFrom with an annotation, and my previous suggestion would introduce an incorrect precedence, the most appropriate fix is to remove line 350 entirely. This will ensure that the loop correctly checks for exact matches first, preserving the intended precedence, and then falls back to the java.io.Serializable handling if no more specific serializer is found.
To implement this, you would remove the following line:
if (entry.getKey().isAssignableFrom(Serializable.class)) continue;This would leave the code block as:
for (SerializerRegistration entry : registrations) {
// If the class is already registered, return its registration
if (entry.getKey().equals(cls)) {
return entry;
}
}The fix you implemented on line 356 (changing Serializable.class to java.io.Serializable.class) remains correct and essential for handling standard Java serialization properly.
Review of Serializable usage fix
Analysis:
java.io.Serializable.classentry.getKey().isAssignableFrom(Serializable.class)- this may also need reviewOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.